#pragma once

#include "../../../Libs/headers.default.h"
#include "../../../Libs/headers.cv.h"
#include "../../../Libs/headers.classification.h"
#include "../../../Libs/headers.ipfe.h"
#include "../../../Libs/headers.and_or_tree.h"

using namespace loirey;

namespace hi_boost
{
	//class CBasicNodeInstance
	//{
	//public:
	//	double x, y, rotation, inferance_scale;
	//	bool fIsMissing;

	//public:
	//	CBasicNodeInstance();
	//	void Clear(bool fIsMissing = true);
	//	void Enable(double x, double y, double rotation, double inferance_scale);
	//	void Disable();
	//};

	//class CNodeInstanceSet
	//{
	//public:
	//	int NodeAmount;
	//	CSimpleTypeArray<CBasicNodeInstance> List_PerNodeInstance;

	//public:
	//	int InputAnnotationFromStream(istream& inStream, int NodeAmount);
	//	int GetInstanceAmount() const;
	//	//void DoTransformation(const CCoordinateTransformer* pCoordinateTransformer);
	//	void DoTransformation(const CZoomConfig& ZoomConfig);
	//};

	//class CGroundTruthAnnotation : public CNodeInstanceSet
	//{
	//public:
	//	int ImageIndex;
	//	int ObjectIndex;
	//	bool fIsFlipped;

	//public:
	//	void LoadFromFile(string strFN_Annotation, int NodeAmount);
	//	bool operator < (const CGroundTruthAnnotation& AnotherInstance) const;
	//};
};

class CHiBoostNodeInstanceBoxConfig
{
public:
	const and_or_tree::CAbstractTree* pTree;
	double MinBoundingBoxRelativeScale_X;
	double MinBoundingBoxRelativeScale_Y;
};

class CHiBoostNodeInstanceBoxSet
{
public:
	static CHiBoostNodeInstanceBoxConfig s_Config;
public:
	CSimpleTypeArray<double> Leaf_X_List;
	CSimpleTypeArray<double> Leaf_Y_List;
public:
	double Center_X;
	double Center_Y;
	CRectBox<double> All_BoundingBox;

public:
	void InitLeafInstanceSet(const double* pX, const double* pY);
	void InitLeafInstanceSet(const CSimpleTypeArray<double>& Leaf_X_List, const CSimpleTypeArray<double>& Leaf_Y_List);
	void RefreshLeafInstanceSet();
	static int GetLeafAmount()
	{
		return (s_Config.pTree==NULL ? 0 : s_Config.pTree->LeafNodeAmount);
	}
	const double* GetPtrLeaf_X() const;
	const double* GetPtrLeaf_Y() const;
public:
	void ComputeNodeCenter(double& DstX, double& DstY, int NodeIndex) const;
	void ComputeNodeBoundingBox(CRectBox<double>& DstBoundingBox, int NodeIndex) const;
	void ComputeNodeBoundingBoxCenter(double& DstX, double& DstY, int NodeIndex) const;
public:
	void DoTRS(const C_TRSable_Image::CParameters& trsConfig);
	void DoTransformation(const CCoordinateTransformer* pCoordinateTransformer);
	void DoTransformation(const CImageTransformation& ImageTransformation);
};

class CHiBoostGroundTruth : public CHiBoostNodeInstanceBoxSet
{
public:
	int MaterialIndex;
	int ObjectIndex;
	bool fIsFlipped;

public:
	void myInit(string strFN_GroundTruth);
};

//class CHiBoostNodeContextConfig
//{
//public:
//	class CNode
//	{
//	public:
//		double xScale;
//		double yScale;
//		double xOffset;
//		double yOffset;
//
//		int Context_W;
//		int Context_H;
//
//		int CellWidth;
//		int CellHeight;
//
//	public:
//		bool InputFromStream(istream& inStream);
//	};
//
//public:
//	CNode GlobalObject;
//	int Size;
//	CSimpleTypeArray<int> HeaderList;
//	CSimpleTypeArray<CNode> Data;
//
//public:
//	CHiBoostNodeContextConfig();
//	void Clear();
//	void myInit(string strFN_ScaleLevelConfig);
//	const CNode& GetDataForNode(int NodeIndex) const;
//public:
//	static void ModifyBox_New(CRectBox<double>& DstBox, double x, double y, double inference_scale, const CNode& Data);
//	static void InverseModifyBox_New(double& DstX, double& DstY, double& DstInferenceScale, const CRectBox<double>& SrcBox, const CNode& Data);
//public:
//public:
//	void GetContextBoxForNodeInstance(CRectBox<double>& DstBox, double x, double y, double inference_scale) const;
//	void GetContextBoxForNodeInstance(CRectBox<double>& DstBox, double x, double y, double inference_scale, int NodeIndex) const;
//public:
//	void GetNodeInstanceByContextBox(
//		double& DstX, double& DstY, double& DstImagePyramidLayerScale, 
//		const CRectBox<double>& SrcBox, int NodeIndex
//		) const;
//	void GetNodeInstanceByContextBox(
//		double& DstX, double& DstY, double& DstImagePyramidLayerScale, 
//		const CImagePyramidPosition& ipp, int NodeIndex
//		) const;
//};

